/**
 * 
 */
package info.niwota.web.apache;

import info.niwota.commons.MimeTypes;
import info.niwota.web.Debug;
import info.niwota.web.Session;
import info.niwota.web.SessionManager;

import java.io.UnsupportedEncodingException;

import x.org.apache.http.HttpRequest;
import x.org.apache.http.HttpResponse;
import x.org.apache.http.protocol.HttpContext;
import android.content.Context;
import android.util.Log;

/**
 * @author qiangli
 * 
 */
public class HttpDispatcher extends BaseHandler {

	private static final String TAG = "HttpDispatcher";

	private HomeHandler homeHandler;
	private LoginHandler loginHandler;
	private ContentHandler contentHandler;
	private ResourceHandler resourceHandler;
	private BinHandler binHandler;
	private DefaultHandler defaultHandler;
	

	/**
	 * @param ctx
	 */
	public HttpDispatcher(Context ctx) {
		super(ctx);
		//
		init();
	}

	private void init() {
		resourceHandler = new ResourceHandler(ctx);
		homeHandler = new HomeHandler(ctx);
		loginHandler = new LoginHandler(ctx);
		contentHandler = new ContentHandler(ctx);
		binHandler = new BinHandler(ctx);
		
		defaultHandler = new DefaultHandler(ctx);
	}

	@Override
	public boolean handle(String p, HttpRequest request, HttpResponse response,
			HttpContext context) {
		try {
			if (!dispatch(p, request, response, context)) {
				sendNotFound(request, response, p);
			}
		} catch (Exception e) {
			if (Debug.DEBUG) {
				e.printStackTrace();
			}
			try {
				sendError(request, response, e);
			} catch (UnsupportedEncodingException e1) {
				e1.printStackTrace();
			}
		}
		return true;
	}

	private boolean dispatch(String p, HttpRequest request,
			HttpResponse response, HttpContext context) throws Exception {
		Session s = getSession(context);
		
		if (Debug.DEBUG) {
			Log.d(TAG, "dispatch: path: " + p + " session: " + s);
		}
		
		/* logout */ 
		if (p.startsWith("/logout")) {
			if (s != null) {
				String sid = s.id;
				if (Debug.DEBUG) {
					Log.d(TAG, "dispatch logout  sid: " + sid);
				}
				SessionManager.remove(sid);
			}
			redirectHome(request, response);
			return true;
		}
		
		/**/
		if (p.startsWith("/proxy.pac") || p.startsWith("/assets/proxy.pac")) {
			final String etag = "proxy"+System.currentTimeMillis();	
			sendAsset(request, response, context, "proxy.pac", MimeTypes.APPLICATION_PAC, etag);
			return true;
		}
		
		/* public resource, login not required */
		if (resourceHandler.handle(p, request, response, context)) {
			return true;
		}
	
		/* /login */
		if (loginHandler.handle(p, request, response, context)) {
			return true;
		}
		
		/*  / /home */
		if (homeHandler.handle(p, request, response, context)) {
			return true;
		}
		
		if (contentHandler.handle(p, request, response, context)) {
			return true;
		}
		
		if (binHandler.handle(p, request, response, context)) {
			return true;
		}
		
		//
		if (defaultHandler.handle(p, request, response, context)) {
			return true;
		}

		if (Debug.DEBUG) {
			Log.d(TAG, "no handler available to service this request");
		}
		
		return false;
	}

}
